home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 June / EnigmA AMIGA RUN 08 (1996)(G.R. Edizioni)(IT)[!][issue 1996-06][EARSAN CD VII].iso / earcd / gcc / ixemlsrc.lha / ixemul / ixnet / res_mkquery.c < prev    next >
C/C++ Source or Header  |  1996-03-13  |  6KB  |  209 lines

  1. /*
  2.  * Copyright (c) 1985 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #if defined(LIBC_SCCS) && !defined(lint)
  35. static char sccsid[] = "@(#)res_mkquery.c    6.16 (Berkeley) 3/6/91";
  36. #endif /* LIBC_SCCS and not lint */
  37.  
  38. #include <sys/param.h>
  39. #include <netinet/in.h>
  40. #include <arpa/nameser.h>
  41. #include <resolv.h>
  42. #include <stdio.h>
  43. #include <string.h>
  44.  
  45. /*
  46.  * Form all types of queries.
  47.  * Returns the size of the result or -1.
  48.  */
  49. int
  50. res_mkquery(op, dname, class, type, data, datalen, newrr, buf, buflen)
  51.     int op;            /* opcode of query */
  52.     const char *dname;        /* domain name */
  53.     int class, type;    /* class and type of query */
  54.     const char *data;        /* resource record data */
  55.     int datalen;        /* length of data */
  56.     const struct rrec *newrr;    /* new rr for modify or append */
  57.     char *buf;        /* buffer to put query */
  58.     int buflen;        /* size of buffer */
  59. {
  60.     register HEADER *hp;
  61.     register char *cp;
  62.     register int n;
  63.     char *dnptrs[10], **dpp, **lastdnptr;
  64.  
  65. #ifdef DEBUG
  66.     if (_res.options & RES_DEBUG)
  67.         printf("res_mkquery(%d, %s, %d, %d)\n", op, dname, class, type);
  68. #endif DEBUG
  69.     /*
  70.      * Initialize header fields.
  71.      */
  72.     if ((buf == NULL) || (buflen < sizeof(HEADER)))
  73.         return(-1);
  74.     bzero(buf, sizeof(HEADER));
  75.     hp = (HEADER *) buf;
  76.     hp->id = htons(++_res.id);
  77.     hp->opcode = op;
  78.     hp->pr = (_res.options & RES_PRIMARY) != 0;
  79.     hp->rd = (_res.options & RES_RECURSE) != 0;
  80.     hp->rcode = NOERROR;
  81.     cp = buf + sizeof(HEADER);
  82.     buflen -= sizeof(HEADER);
  83.     dpp = dnptrs;
  84.     *dpp++ = buf;
  85.     *dpp++ = NULL;
  86.     lastdnptr = dnptrs + sizeof(dnptrs)/sizeof(dnptrs[0]);
  87.     /*
  88.      * perform opcode specific processing
  89.      */
  90.     switch (op) {
  91.     case QUERY:
  92.         if ((buflen -= QFIXEDSZ) < 0)
  93.             return(-1);
  94.         if ((n = dn_comp((u_char *)dname, (u_char *)cp, buflen,
  95.             (u_char **)dnptrs, (u_char **)lastdnptr)) < 0)
  96.             return (-1);
  97.         cp += n;
  98.         buflen -= n;
  99.         __putshort(type, (u_char *)cp);
  100.         cp += sizeof(u_short);
  101.         __putshort(class, (u_char *)cp);
  102.         cp += sizeof(u_short);
  103.         hp->qdcount = htons(1);
  104.         if (op == QUERY || data == NULL)
  105.             break;
  106.         /*
  107.          * Make an additional record for completion domain.
  108.          */
  109.         buflen -= RRFIXEDSZ;
  110.         if ((n = dn_comp((u_char *)data, (u_char *)cp, buflen,
  111.             (u_char **)dnptrs, (u_char **)lastdnptr)) < 0)
  112.             return (-1);
  113.         cp += n;
  114.         buflen -= n;
  115.         __putshort(T_NULL, (u_char *)cp);
  116.         cp += sizeof(u_short);
  117.         __putshort(class, (u_char *)cp);
  118.         cp += sizeof(u_short);
  119.         __putlong(0, (u_char *)cp);
  120.         cp += sizeof(u_long);
  121.         __putshort(0, (u_char *)cp);
  122.         cp += sizeof(u_short);
  123.         hp->arcount = htons(1);
  124.         break;
  125.  
  126.     case IQUERY:
  127.         /*
  128.          * Initialize answer section
  129.          */
  130.         if (buflen < 1 + RRFIXEDSZ + datalen)
  131.             return (-1);
  132.         *cp++ = '\0';    /* no domain name */
  133.         __putshort(type, (u_char *)cp);
  134.         cp += sizeof(u_short);
  135.         __putshort(class, (u_char *)cp);
  136.         cp += sizeof(u_short);
  137.         __putlong(0, (u_char *)cp);
  138.         cp += sizeof(u_long);
  139.         __putshort(datalen, (u_char *)cp);
  140.         cp += sizeof(u_short);
  141.         if (datalen) {
  142.             bcopy(data, cp, datalen);
  143.             cp += datalen;
  144.         }
  145.         hp->ancount = htons(1);
  146.         break;
  147.  
  148. #ifdef ALLOW_UPDATES
  149.     /*
  150.      * For UPDATEM/UPDATEMA, do UPDATED/UPDATEDA followed by UPDATEA
  151.      * (Record to be modified is followed by its replacement in msg.)
  152.      */
  153.     case UPDATEM:
  154.     case UPDATEMA:
  155.  
  156.     case UPDATED:
  157.         /*
  158.          * The res code for UPDATED and UPDATEDA is the same; user
  159.          * calls them differently: specifies data for UPDATED; server
  160.          * ignores data if specified for UPDATEDA.
  161.          */
  162.     case UPDATEDA:
  163.         buflen -= RRFIXEDSZ + datalen;
  164.         if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
  165.             return (-1);
  166.         cp += n;
  167.         __putshort(type, cp);
  168.                 cp += sizeof(u_short);
  169.                 __putshort(class, cp);
  170.                 cp += sizeof(u_short);
  171.         __putlong(0, cp);
  172.         cp += sizeof(u_long);
  173.         __putshort(datalen, cp);
  174.                 cp += sizeof(u_short);
  175.         if (datalen) {
  176.             bcopy(data, cp, datalen);
  177.             cp += datalen;
  178.         }
  179.         if ( (op == UPDATED) || (op == UPDATEDA) ) {
  180.             hp->ancount = htons(0);
  181.             break;
  182.         }
  183.         /* Else UPDATEM/UPDATEMA, so drop into code for UPDATEA */
  184.  
  185.     case UPDATEA:    /* Add new resource record */
  186.         buflen -= RRFIXEDSZ + datalen;
  187.         if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
  188.             return (-1);
  189.         cp += n;
  190.         __putshort(newrr->r_type, cp);
  191.                 cp += sizeof(u_short);
  192.                 __putshort(newrr->r_class, cp);
  193.                 cp += sizeof(u_short);
  194.         __putlong(0, cp);
  195.         cp += sizeof(u_long);
  196.         __putshort(newrr->r_size, cp);
  197.                 cp += sizeof(u_short);
  198.         if (newrr->r_size) {
  199.             bcopy(newrr->r_data, cp, newrr->r_size);
  200.             cp += newrr->r_size;
  201.         }
  202.         hp->ancount = htons(0);
  203.         break;
  204.  
  205. #endif ALLOW_UPDATES
  206.     }
  207.     return (cp - buf);
  208. }
  209.